<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'

const canvasRef = ref<HTMLCanvasElement | null>(null)

// 星星类
class Star {
  x: number
  y: number
  z: number
  size: number
  opacity: number
  blinkSpeed: number // 闪烁速度
  blinkPhase: number // 当前相位
  isBright: boolean // 是否是特亮星

  constructor(width: number, height: number) {
    this.x = (Math.random() - 0.5) * width * 2
    this.y = (Math.random() - 0.5) * height * 2
    this.z = Math.random() * width
    // 10% 的星星是特亮的
    this.isBright = Math.random() < 0.1
    // 特亮星更大
    this.size = this.isBright ? 3.5 : 2.0
    this.opacity = Math.random()
    // 随机闪烁参数
    this.blinkSpeed = Math.random() * 0.05 + 0.01
    this.blinkPhase = Math.random() * Math.PI * 2
  }

  update(width: number, height: number, speed: number) {
    this.z -= speed
    if (this.z <= 0) {
      this.z = width
      this.x = (Math.random() - 0.5) * width * 2
      this.y = (Math.random() - 0.5) * height * 2
    }
    // 更新闪烁
    this.blinkPhase += this.blinkSpeed
  }

  draw(ctx: CanvasRenderingContext2D, width: number, height: number) {
    const x = (this.x / this.z) * width + width / 2
    const y = (this.y / this.z) * height + height / 2
    const radius = (1 - this.z / width) * this.size

    // 边界检查
    if (x < 0 || x > width || y < 0 || y > height) return

    // 计算动态透明度
    let alpha = this.opacity
    if (this.isBright) {
      // 特亮星有明显的呼吸闪烁效果
      alpha = 0.5 + Math.sin(this.blinkPhase) * 0.5
    }

    ctx.beginPath()
    ctx.arc(x, y, radius > 0 ? radius : 0, 0, Math.PI * 2)
    ctx.fillStyle = `rgba(255, 255, 255, ${alpha})`

    // 给特亮星增加光晕
    if (this.isBright && radius > 0) {
      ctx.shadowBlur = 15
      ctx.shadowColor = 'rgba(255, 255, 255, 0.8)'
    } else {
      ctx.shadowBlur = 0
    }

    ctx.fill()
    // 重置 shadow 以免影响后续绘制
    ctx.shadowBlur = 0
  }
}

// 动画逻辑
let animationFrameId: number
const stars: Star[] = []
// 降低速度，方便观察
const SPEED = 0.5
// 增加数量
const STAR_COUNT = 800

function initStars(width: number, height: number) {
  stars.length = 0
  for (let i = 0; i < STAR_COUNT; i++) {
    stars.push(new Star(width, height))
  }
}

function animate() {
  const canvas = canvasRef.value
  if (!canvas) return
  const ctx = canvas.getContext('2d')
  if (!ctx) return

  const width = canvas.width
  const height = canvas.height

  // 清空画布
  ctx.fillStyle = '#0F172A'
  ctx.fillRect(0, 0, width, height)

  stars.forEach((star) => {
    star.update(width, height, SPEED)
    star.draw(ctx, width, height)
  })

  animationFrameId = requestAnimationFrame(animate)
}

function handleResize() {
  if (!canvasRef.value) return
  canvasRef.value.width = window.innerWidth
  canvasRef.value.height = window.innerHeight
  initStars(window.innerWidth, window.innerHeight)
}

onMounted(() => {
  // 确保 Canvas 尺寸正确初始化
  if (canvasRef.value) {
    canvasRef.value.width = window.innerWidth
    canvasRef.value.height = window.innerHeight
    initStars(window.innerWidth, window.innerHeight)
    animate()
  }
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  cancelAnimationFrame(animationFrameId)
})
</script>

<template>
  <!-- 确保 z-index 正确，且 pointer-events-none 防止遮挡交互 -->
  <canvas ref="canvasRef" class="fixed inset-0 w-full h-full z-0 pointer-events-none" />
</template>
